package com.paas.form.service.impl;

import com.paas.common.jdbc.JdbcSql;
import com.paas.common.jdbc.model.DbConfig;
import com.paas.common.jdbc.model.DbResult;
import com.paas.common.util.BeanUtil;
import com.paas.common.util.StringUtil;
import com.paas.form.entity.FormDataChangeInfoEntity;
import com.paas.plus.tool.form.model.*;
import com.paas.plus.tool.form.server.FormService;
import com.paas.plus.tool.form.util.JdbcParamUtil;
import com.paas.plus.tool.form.util.TransformDateUtil;
import com.paas.plus.tool.realTimeDistributed.model.RealTimeDistributionVo;
import com.paas.plus.tool.realTimeDistributed.server.IRealTimeDistributeServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.paas.form.dao.FormDataChangeInfoDao;
import com.paas.form.service.IFormDataChangeInfoService;
import com.paas.common.web.service.BaseServiceImpl;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

@Service("dataChangeInfoService")
public class FormDataChangeInfoServiceImpl extends BaseServiceImpl<FormDataChangeInfoDao, FormDataChangeInfoEntity> implements IFormDataChangeInfoService {


    @Autowired
    public IRealTimeDistributeServer realTimeDistributeServer;

    @Autowired
    public FormService formService;

    @Override
    public Boolean viewDataChange(DataChange dataChange) throws Exception {
        //查询变更主表数据
        DataChangeInfo dataChangeInfo = formService.getDataChangeInfoById(dataChange.getDataChangeInfoId());
        if (StringUtil.isNotEmpty(dataChangeInfo.getType())) {
            //类型(1:申请 2：变更 3：删除 4：启用 5：停用)
            switch (dataChangeInfo.getType()) {
                case "1":
                    //DataAddChange(dataIds, jdbcSql, dataChangeInfoDetails, views);
                    this.saveDataChange(dataChangeInfo);
                    break;
                case "2":
                    //DataEditChange(dataIds, jdbcSql, dataChangeInfoDetails, views, dataChangeInfo);
                    this.saveDataChange(dataChangeInfo);
                    break;
                case "3":
                    DataStatusChange(dataChangeInfo,  "0");
                    break;
                case "4":
                    DataStatusChange(dataChangeInfo, "1");
                    break;
                case "5":
                    DataStatusChange(dataChangeInfo,  "2");
                    break;
                default:
                    break;
            }
        } else {
            return false;
        }
        return true;
    }

    private void saveDataChange(DataChangeInfo dataChangeInfo)  throws Exception{
        List<DataChangeInfoDetail> dataChangeInfoDetails = formService.getDetailsByChangeInfoId(dataChangeInfo.getId());
        String viewId = dataChangeInfo.getViewDataId();
        //主表视图
        View masterView = formService.getViewById(viewId);
        if(BeanUtil.isEmpty(masterView)){
            return ;
        }
        List<String> viewIds = new ArrayList<>();
        viewIds.add(viewId);//添加主视图
        //查询子视图
        List<View> childViews =  formService.getChildViewById(viewId);
        if(BeanUtil.isNotEmpty(childViews)){
            List<String> childViewIds = childViews.stream().map(View::getId).collect(Collectors.toList());
            viewIds.addAll(childViewIds);
        }
        //获取视图属性配置
        List<Attribute> attributeList = formService.getAttributeByViewIds(viewIds);
        //根据视图id分组
        Map<String, List<Attribute>> attributeMap = attributeList.stream().collect(Collectors.groupingBy(Attribute::getViewId));
        //根据视图id分组， 区分出主表与明细表的数据
        Map<String, List<DataChangeInfoDetail>> tableChangeInfoMap = dataChangeInfoDetails.stream().collect(Collectors.groupingBy(DataChangeInfoDetail::getViewId));
        String masterViewId = null;

        Map<String,Object> defaultValueMap = new HashMap<>();
        defaultValueMap.put("sysTime",new Date());

        DbConfig dbConfig = formService.getViewByDatasourceId(masterView.getDatasourceId());
        JdbcSql jdbcSql = new JdbcSql(dbConfig);
        /**
         * 定义实时分发对象
         */
        RealTimeDistributionVo realTimeDistributionVo = new RealTimeDistributionVo();
        realTimeDistributionVo.setViewId(masterView.getId());
        realTimeDistributionVo.setPrimaryKeyField(masterView.getIdField());//主视图主键设置
        //分发数据
        ArrayList<HashMap<String,Object>>  masterViewDistributionDataList = new ArrayList<>();

        //处理主视图数据
        if(tableChangeInfoMap.containsKey(masterView.getId())){
            //主视图数据明细
            List<DataChangeInfoDetail> masterViewDataDetails = tableChangeInfoMap.get(masterView.getId());
            if ("2".equals(masterViewDataDetails.get(0).getType())) {
                //处理修改
                JdbcUpdateParams jdbcUpdateParams =getViewUpdateParams(masterView,attributeMap.get(masterView.getId()),masterViewDataDetails);
                masterViewId = jdbcUpdateParams.getIdValue();
                //执行数据修改
                JdbcParamUtil.executeViewUpdate(jdbcUpdateParams,jdbcSql);

                //实时分发数据设置
                realTimeDistributionVo.setType("update");
                List<String> masterViewIdList = new ArrayList<>();
                masterViewIdList.add(masterViewId);
                //获取实时分发数据，查询数据库最新的
                Map<String,Map<String, Object>> masterViewDataMap = JdbcParamUtil.getChildViewData(masterViewIdList,masterView,jdbcSql);
                //获取实时分发数据
                HashMap<String,Object> masterViewDistributionDataMap = (HashMap<String, Object>) masterViewDataMap.get(masterViewId);
                masterViewDistributionDataList.add(masterViewDistributionDataMap);
            }else{
                //处理新增
                JdbcInsertParams jdbcInsertParams = new JdbcInsertParams();
                setViewInsertParams(masterView,attributeMap.get(masterView.getId()),masterViewDataDetails,jdbcInsertParams,defaultValueMap,null);
                masterViewId = jdbcInsertParams.getIdValues().get(0);
                //执行数据新增
                JdbcParamUtil.executeViewInsert(jdbcInsertParams,jdbcSql);

                //实时分发数据设置
                realTimeDistributionVo.setType("insert");
                masterViewDistributionDataList = JdbcParamUtil.getDistributeDataForInsert(jdbcInsertParams);
            }
        }else{
            //实时分发数据设置
            masterViewId = dataChangeInfo.getMasterViewEditDataId();
            realTimeDistributionVo.setType("update");
            List<String> masterViewIdList = new ArrayList<>();
            masterViewIdList.add(masterViewId);
            //获取实时分发数据，查询数据库最新的
            Map<String,Map<String, Object>> masterViewDataMap = JdbcParamUtil.getChildViewData(masterViewIdList,masterView,jdbcSql);
            //获取实时分发数据
            HashMap<String,Object> masterViewDistributionDataMap = (HashMap<String, Object>) masterViewDataMap.get(masterViewId);
            masterViewDistributionDataList.add(masterViewDistributionDataMap);
        }
        //设置实时分发主视图数据
        realTimeDistributionVo.setArrayList(masterViewDistributionDataList);


        if(BeanUtil.isNotEmpty(childViews)) {
            //处理子视图数据
            for (View childView : childViews) {
                //判断当前子视图是否配置属性
                if (!attributeMap.containsKey(viewId)) {
                    continue;
                }
                if(!tableChangeInfoMap.containsKey(childView.getId())){
                    continue;
                }
                //修改
                List<JdbcUpdateParams> jdbcUpdateParamsList = new ArrayList<>();

                //获取子视图数据
                List<DataChangeInfoDetail> childViewDataDetails = tableChangeInfoMap.get(childView.getId());
                Map<String, List<DataChangeInfoDetail>> insertItemMap = new HashMap<String, List<DataChangeInfoDetail>>();

                for (DataChangeInfoDetail dataChangeInfoDetail : childViewDataDetails) {
                    String primaryKeyValue = dataChangeInfoDetail.getPrimaryKeyValue();
                    if(StringUtil.isEmpty(primaryKeyValue)){
                        primaryKeyValue = "pkeynull";
                    }
                    List<DataChangeInfoDetail> groupDataList = new ArrayList<>();
                    if(insertItemMap.containsKey(primaryKeyValue))           {
                        groupDataList = insertItemMap.get(primaryKeyValue);
                    }
                    groupDataList.add(dataChangeInfoDetail);
                    insertItemMap.put(primaryKeyValue, groupDataList);
                }
                //新增处理类
                JdbcInsertParams jdbcInsertParams = new JdbcInsertParams();
                //根据主键分组后数据逐条处理
                for (List<DataChangeInfoDetail> itemList : insertItemMap.values()) {
                    if ("2".equals(itemList.get(0).getType())) {
                        JdbcUpdateParams jdbcUpdateParams =getViewUpdateParams(childView,attributeMap.get(childView.getId()),itemList);
                        //添加修改数据至集合
                        jdbcUpdateParamsList.add(jdbcUpdateParams);
                    }else{
                        setViewInsertParams(childView,attributeMap.get(childView.getId()),itemList,jdbcInsertParams,defaultValueMap,masterViewId);
                    }
                }

                /**
                 * 当前子视图数据新增处理逻辑
                 */
                if(jdbcInsertParams.getColumn()!=null && jdbcInsertParams.getDatas()!=null){
                    //执行数据新增
                    JdbcParamUtil.executeViewInsert(jdbcInsertParams,jdbcSql);
                    //定义子视图分发对象
                    RealTimeDistributionVo childInsertDistributionVo = new RealTimeDistributionVo();
                    childInsertDistributionVo.setViewId(childView.getId());
                    childInsertDistributionVo.setType("insert");
                    childInsertDistributionVo.setDataName(childView.getContainerField());
                    childInsertDistributionVo.setPrimaryKeyField(childView.getIdField());
                    childInsertDistributionVo.setArrayList(JdbcParamUtil.getDistributeDataForInsert(jdbcInsertParams));
                    if(BeanUtil.isEmpty(realTimeDistributionVo.getRealTimeDistributionVos())){
                        realTimeDistributionVo.setRealTimeDistributionVos(new ArrayList<>());
                    }
                    realTimeDistributionVo.getRealTimeDistributionVos().add(childInsertDistributionVo);
                }

                /**
                 * 当前子视图数据修改处理逻辑
                 */
                if(jdbcUpdateParamsList!=null && jdbcUpdateParamsList.size()>0){
                    //执行数据修改
                    JdbcParamUtil.executeViewUpdate(jdbcUpdateParamsList,jdbcSql);

                    List<String> childViewDataIds = jdbcUpdateParamsList.stream().map(JdbcUpdateParams::getIdValue).collect(Collectors.toList());
                    //获取实时分发数据，查询数据库最新的
                    Map<String,Map<String, Object>> childViewDataMap = JdbcParamUtil.getChildViewData(childViewDataIds,childView,jdbcSql);
                    //定义子视图分发对象
                    RealTimeDistributionVo childUpdateDistributionVo = new RealTimeDistributionVo();
                    //分发数据
                    ArrayList<HashMap<String,Object>>  childViewDistributionDataList = new ArrayList<>();
                    for(Map<String, Object> childViewDataItem:childViewDataMap.values()){
                        childViewDistributionDataList.add((HashMap<String, Object>) childViewDataItem);
                    }
                    childUpdateDistributionVo.setViewId(childView.getId());
                    childUpdateDistributionVo.setType("update");
                    childUpdateDistributionVo.setDataName(childView.getContainerField());
                    childUpdateDistributionVo.setPrimaryKeyField(childView.getIdField());
                    childUpdateDistributionVo.setArrayList(childViewDistributionDataList);
                    if(BeanUtil.isEmpty(realTimeDistributionVo.getRealTimeDistributionVos())){
                        realTimeDistributionVo.setRealTimeDistributionVos(new ArrayList<>());
                    }
                    realTimeDistributionVo.getRealTimeDistributionVos().add(childUpdateDistributionVo);
                }
            }
        }
        List<RealTimeDistributionVo> realTimeDistributionVoList = new ArrayList<RealTimeDistributionVo>();
        realTimeDistributionVoList.add(realTimeDistributionVo);
        try {
            realTimeDistributeServer.getRealTimeDistributeResult(realTimeDistributionVoList);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("分发出错");
        }

    }

    private void DataStatusChange(DataChangeInfo dataChangeInfo, String statusValue) throws Exception {
        List<DataChangeInfoDetail> dataChangeInfoDetails = formService.getDetailsByChangeInfoId(dataChangeInfo.getId());
        if (dataChangeInfoDetails.size() > 0) {
            DataChangeInfoDetail detailItem = dataChangeInfoDetails.get(0);
            View view = formService.getViewById(detailItem.getViewId());
            if (BeanUtil.isNotEmpty(view)) {
                JdbcUpdateParams jdbcUpdateParams = new JdbcUpdateParams();
                jdbcUpdateParams.setLinkTable(view.getLinkTable());
                jdbcUpdateParams.setIdKey(detailItem.getPrimaryKeyField());
                jdbcUpdateParams.setIdValue(detailItem.getPrimaryKeyValue());

                List<String> columns = new ArrayList<>();
                //定义字段更新值集合
                List<Object> datas =new ArrayList<>();
                //添加更新字段key
                columns.add(view.getStatusField());
                //添加更新字段值
                datas.add(statusValue);
                jdbcUpdateParams.setColumn(columns);
                jdbcUpdateParams.setDatas(datas);

                DbConfig dbConfig = formService.getViewByDatasourceId(view.getDatasourceId());
                JdbcSql jdbcSql = new JdbcSql(dbConfig);
                //执行数据修改
                JdbcParamUtil.executeViewUpdate(jdbcUpdateParams,jdbcSql);

                /**
                 * 定义实时分发对象
                 */
                RealTimeDistributionVo realTimeDistributionVo = new RealTimeDistributionVo();
                realTimeDistributionVo.setViewId(detailItem.getViewId());
                realTimeDistributionVo.setPrimaryKeyField(view.getIdField());//视图主键设置
                //实时分发数据设置
                realTimeDistributionVo.setType("update");

                //分发数据
                ArrayList<HashMap<String,Object>>  viewDistributionDataList = new ArrayList<>();

                List<String> viewIdList = new ArrayList<>();
                viewIdList.add(detailItem.getPrimaryKeyValue());
                //获取实时分发数据，查询数据库最新的
                Map<String,Map<String, Object>> masterViewDataMap = JdbcParamUtil.getChildViewData(viewIdList,view,jdbcSql);
                //获取实时分发数据
                HashMap<String,Object> masterViewDistributionDataMap = (HashMap<String, Object>) masterViewDataMap.get(detailItem.getPrimaryKeyValue());
                viewDistributionDataList.add(masterViewDistributionDataMap);
                realTimeDistributionVo.setArrayList(viewDistributionDataList);

                List<RealTimeDistributionVo> realTimeDistributionVoList = new ArrayList<RealTimeDistributionVo>();
                realTimeDistributionVoList.add(realTimeDistributionVo);
                try {
                    realTimeDistributeServer.getRealTimeDistributeResult(realTimeDistributionVoList);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("分发出错");
                }
            }
        }
    }


    //视图新增参数设置
    private void setViewInsertParams(View view, List<Attribute> attributeList, List<DataChangeInfoDetail> dataChangeInfoDetailList,JdbcInsertParams jdbcInsertParams , Map<String,Object> defaultValueMap ,String parentId) throws ParseException {
        //数据转换，key为字段属性编码 ，value为对应数据
        Map<String, DataChangeInfoDetail> itemMap = dataChangeInfoDetailList.stream().collect(Collectors.toMap(DataChangeInfoDetail::getAttributeName, t->t));
        //新增字段列
        List<String> addColumns = new ArrayList<>();
        //定义数据存储列
        List<Object> cloumnValues = new ArrayList<Object>();

        String idValue =getUUID();

        //根据属性设置字段
        for(Attribute attribute:attributeList){
            String field = attribute.getField();
            if(StringUtil.isEmpty(field)){
                field = attribute.getCode();
            }
            Object valuesItem = null;
            //兼容字段大小写问题
            if(itemMap.containsKey(field)){
                valuesItem = itemMap.get(field).getUpdateValue();
            }else if(itemMap.containsKey(field.toLowerCase())){
                valuesItem = itemMap.get(field.toLowerCase()).getUpdateValue();
            }else if(itemMap.containsKey(field.toUpperCase())){
                valuesItem = itemMap.get(field.toUpperCase()).getUpdateValue();
            }
            if(BeanUtil.isEmpty(valuesItem)){
                //兼容处理默认值
                if("defaultSysValue".equals(attribute.getReferenceType())){
                    if(defaultValueMap.containsKey(attribute.getReferenceData())){
                        valuesItem = defaultValueMap.get(attribute.getReferenceData());
                    }
                }
                //主键默认值
                if(compareIgnoreCase(field,view.getIdField())){
                    valuesItem = idValue;
                }else if(compareIgnoreCase(field,view.getForeignKeyMapping())){
                    //父id值处理
                    valuesItem = parentId;
                }
            }else{
                //判断主键和父id，是否传值
                if(compareIgnoreCase(field,view.getIdField())){
                    //主键传值了，则以传递值为准
                    idValue = valuesItem.toString();
                }
            }
            if(BeanUtil.isNotEmpty(valuesItem)){
                //不同类型做数据转换 1：date:2：number:3：string
                valuesItem = TransformDateUtil.dataTypeConversion(valuesItem,attribute);
            }

            //新增数据业务处理
            addColumns.add(field); //字段添加
            cloumnValues.add(valuesItem); //值添加
        }
        List<List<Object>> datas = jdbcInsertParams.getDatas();
        if(BeanUtil.isEmpty(datas)){
            datas = new ArrayList<>();
        }
        if(BeanUtil.isEmpty(jdbcInsertParams.getIdValues())){
            jdbcInsertParams.setIdValues(new ArrayList<>());
        }
        jdbcInsertParams.getIdValues().add(idValue);
        datas.add(cloumnValues);
        jdbcInsertParams.setColumn(addColumns);
        jdbcInsertParams.setDatas(datas);
        jdbcInsertParams.setLinkTable(view.getLinkTable());
    }

    //视图修改参数设置
    private JdbcUpdateParams getViewUpdateParams(View view, List<Attribute> attributeList, List<DataChangeInfoDetail> dataChangeInfoDetailList) throws ParseException {
        //数据转换，key为字段属性编码 ，value为对应数据
        Map<String, DataChangeInfoDetail> itemMap = dataChangeInfoDetailList.stream().collect(Collectors.toMap(DataChangeInfoDetail::getAttributeName, t->t));
        String idValue= dataChangeInfoDetailList.get(0).getPrimaryKeyValue();
        //修改字段列
        List<String> updateColumns = new ArrayList<>();
        //定义数据存储列
        List<Object> cloumnValues = new ArrayList<Object>();
        for(Attribute attribute:attributeList){
            String field = attribute.getField();
            if(StringUtil.isEmpty(field)){
                field = attribute.getCode();
            }
            Object valuesItem = null;
            //兼容字段大小写问题
            if(itemMap.containsKey(field)){
                valuesItem = itemMap.get(field).getUpdateValue();
            }else if(itemMap.containsKey(field.toLowerCase())){
                valuesItem = itemMap.get(field.toLowerCase()).getUpdateValue();
            }else if(itemMap.containsKey(field.toUpperCase())){
                valuesItem = itemMap.get(field.toUpperCase()).getUpdateValue();
            }
            //值不为空才处理
            if(BeanUtil.isNotEmpty(valuesItem)){
                //不同类型做数据转换 1：date:2：number:3：string
                valuesItem = TransformDateUtil.dataTypeConversion(valuesItem,attribute);
                updateColumns.add(field);
                cloumnValues.add(valuesItem);
            }else if(itemMap.containsKey(field) || itemMap.containsKey(field.toLowerCase()) || itemMap.containsKey(field.toUpperCase())){
                //变更为空的情况
                updateColumns.add(field);
                cloumnValues.add(valuesItem);
            }
        }
        JdbcUpdateParams jdbcUpdateParams = new JdbcUpdateParams();
        jdbcUpdateParams.setLinkTable(view.getLinkTable());
        jdbcUpdateParams.setIdKey(view.getIdField());
        jdbcUpdateParams.setIdValue(idValue);
        jdbcUpdateParams.setColumn(updateColumns);
        jdbcUpdateParams.setDatas(cloumnValues);
        return jdbcUpdateParams;
    }

    private boolean compareIgnoreCase(String str1,String s2) {
        if (StringUtil.isEmpty(str1) && StringUtil.isEmpty(s2)) {
            return true;
        } else if (StringUtil.isEmpty(str1) || StringUtil.isEmpty(s2)) {
            return false;
        } else {
            if (str1.equals(s2) || str1.toUpperCase().equals(s2.toUpperCase())) {
                return true;
            } else {
                return false;
            }
        }
    }

    private static String getUUID() {
        String uuid = UUID.randomUUID().toString();
        uuid = uuid.replace("-", "");
        return uuid;
    }
	
}